// 蜂窝蜜造平台生成代码，此文件只生成一次，不需要添加到 .beeignore

package com.fowo.api.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.entity.*;
import com.fowo.api.model.supplier.flow.node.SupplierFlowNodeEnum;
import com.fowo.api.model.supplier.patrol.task.SupplierPatrolTaskVo;
import com.fowo.api.model.supplier.task.SupplierTaskVo;
import com.fowo.api.model.supplier.task.instance.SupplierTaskInstanceVo;
import com.fowo.api.service.SupplierTaskService;
import com.fowo.api.sys.annotation.DataActivity;
import com.fowo.api.sys.entity.enums.SysDataActivityAction;
import com.fowo.api.user.model.JwtUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 供应商产品开发任务 服务实现类
 */
@Service
@Slf4j
public class SupplierTaskServiceImpl extends SupplierTaskBaseServiceImpl implements SupplierTaskService {

    @Resource
    private SupplierFlowNodeServiceImpl supplierFlowNodeService;


    @DataActivity(action = SysDataActivityAction.Add)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long create(SupplierTaskVo model) throws Exception {
        Assert.isTrue(ObjUtil.isNotEmpty(model), "参数异常!");
        try {
            SupplierFlowNode node = supplierFlowNodeService.getNode(model.getEnCode(), null);
            Long id = super.create(model);
            model.setId(id);
            supplierFlowNodeService.process(CollUtil.newArrayList(model), node, node.getNode(), null, item -> {
            });
            return id;
        } catch (Exception ex) {
            log.error("发生异常,异常信息:" + StrUtil.subPre(ExceptionUtil.getRootCauseMessage(ex), 2000));
            throw new RuntimeException("发生异常,信息:" + StrUtil.subPre(ExceptionUtil.getRootCauseMessage(ex), 2000));
        }

    }

    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了提交操作"
    )
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void doSubmit(List<Long> ids) throws Exception {
        Assert.isTrue(CollUtil.isNotEmpty(ids), "参数异常!");
        List<SupplierTask> list = this.listByIds(ids);
        SupplierFlowNode node = supplierFlowNodeService.getConditionNode(list);
        supplierFlowNodeService.process(list, node, node.getNode(), CollUtil.newArrayList(node.getNodeUp()), item -> {
        });
        this.updateBatchById(list);
    }

    /**
     * 取消提交
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了取消提交操作"
    )
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void unDoSubmit(List<Long> ids) throws Exception {
        Assert.isTrue(CollUtil.isNotEmpty(ids), "参数异常!");
        List<SupplierTask> list = this.listByIds(ids);
        SupplierFlowNode node = supplierFlowNodeService.getConditionNode(list);
        supplierFlowNodeService.process(list, node, node.getNodeExceptionStatus(), CollUtil.newArrayList(node.getNodeUp()), item -> {
            Assert.isTrue(StrUtil.isNotBlank(node.getNodeExceptionStatus()), "没有配置异常节点!");
            SupplierTaskInstance supplierTaskInstance = SpringUtil.getBean(SupplierTaskInstanceServiceImpl.class).getOne(Wrappers.<SupplierTaskInstance>lambdaQuery().eq(SupplierTaskInstance::getTaskId, item.getId())
                    .eq(SupplierTaskInstance::getStatus, "6"), false);
            Assert.isTrue(ObjUtil.isEmpty(supplierTaskInstance), "任务已执行,不可取消!", supplierTaskInstance.getInstanceId());
            supplierTaskInstance.setStatus(node.getNodeExceptionStatus());
            SpringUtil.getBean(SupplierTaskInstanceServiceImpl.class).updateById(supplierTaskInstance);
        });
        this.updateBatchById(list);
    }

    /**
     * 拾取
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了拾取操作"
    )
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void doReceive(List<Long> ids) throws Exception {
        Assert.isTrue(CollUtil.isNotEmpty(ids), "参数异常!");
        JwtUserInfo currentUser = JwtUserInfo.fromHeader();
        Assert.isTrue(ObjUtil.isNotEmpty(currentUser), "请先登录!");
        List<SupplierTask> list = this.listByIds(ids);
        SupplierFlowNode node = supplierFlowNodeService.getConditionNode(list);
        supplierFlowNodeService.process(list, node, node.getNodeUp(), null, item -> {
            SupplierTaskInstance supplierTaskInstance = SpringUtil.getBean(SupplierTaskInstanceServiceImpl.class).getOne(Wrappers.<SupplierTaskInstance>lambdaQuery().eq(SupplierTaskInstance::getTaskId, item.getId())
                    .eq(SupplierTaskInstance::getStatus, node.getNode()), false);
            if (ObjUtil.isNotEmpty(supplierTaskInstance)) {
                Assert.isTrue(!CollUtil.safeContains(CollUtil.newArrayList(supplierTaskInstance.getDoUser()), currentUser.getUserId()), "重复拾取,单号:{}请检查!", supplierTaskInstance.getInstanceId());
            }
            Assert.isTrue(CollUtil.safeContains(item.getToUser(), currentUser.getUserId()), "拾取错误,您不可拾取!");
            //创建实例
            SupplierTaskInstanceVo model = new SupplierTaskInstanceVo();
            model.setTaskId(item.getId());
            model.setProductId(item.getProductId());
            model.setEndTime(item.getEndTime());
            model.setDoUser(currentUser.getUserId());
            model.setStatus(node.getNode());
            try {
                SpringUtil.getBean(SupplierTaskInstanceServiceImpl.class).create(model);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
        this.updateBatchById(list);
    }

    /**
     * 撤销
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了撤销操作"
    )
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void doRevoke(List<Long> ids) throws Exception {
        Assert.isTrue(CollUtil.isNotEmpty(ids), "参数异常!");
        List<SupplierTask> list = this.listByIds(ids);
        SupplierFlowNode node = supplierFlowNodeService.getConditionNode(list);
        supplierFlowNodeService.process(list, node, SupplierFlowNodeEnum.关闭.getValue(), CollUtil.newArrayList(SupplierFlowNodeEnum.已提交.getValue(), SupplierFlowNodeEnum.已接收.getValue()), item -> {
            Assert.isTrue(StrUtil.isNotBlank(node.getNodeExceptionStatus()), "没有配置异常节点!");
            Assert.isTrue(StrUtil.isNotBlank(node.getNodeDownExceptionStatus()), "没有配置异常下游节点!");
            //撤销实例
            SpringUtil.getBean(SupplierTaskInstanceServiceImpl.class).update(Wrappers.<SupplierTaskInstance>lambdaUpdate()
                    .set(SupplierTaskInstance::getStatus, node.getNodeDownExceptionStatus())
                    .eq(SupplierTaskInstance::getTaskId, item.getId()));
        });
        this.updateBatchById(list);
    }


    /**
     * 扫描配置创建任务
     */
    public void scanConfigCreateSupplierTask() throws Exception {
        List<SupplierSet> configList = SpringUtil.getBean(SupplierSetServiceImpl.class).list(Wrappers.<SupplierSet>lambdaQuery().eq(SupplierSet::getStatus, "1"));
        for (SupplierSet supplierSet : configList) {
            for (Long toUser : supplierSet.getToUser()) {
                //单量超过巡场周期订单量&待到货状态的供应商
                List<PurchaseOrder> purchaseOrderList = SpringUtil.getBean(PurchaseOrderServiceImpl.class).list(Wrappers.<PurchaseOrder>query().select("DISTINCT supplier_id").lambda()
                        .eq(PurchaseOrder::getAnStatus, "2")
                        .eq(PurchaseOrder::getProductType, "1")
                        .gt(PurchaseOrder::getPurchaseQuantity, supplierSet.getPatrolOrderQuantity()));
                for (PurchaseOrder purchaseOrder : purchaseOrderList) {
                    //创建提交的后的巡场单据
                    SupplierPatrolTaskVo model = new SupplierPatrolTaskVo();
                    model.setTitle("供应商巡场周期任务");
                    model.setPurchaseId(CollUtil.newArrayList(purchaseOrder.getId()));
                    model.setSupplierId(CollUtil.newArrayList(purchaseOrder.getSupplierId()));
                    model.setGrade(supplierSet.getGrade());
                    model.setStatus("1");
                    model.setToUser(toUser);
                    //创建并提交
                    Long patrolTaskId = SpringUtil.getBean(SupplierPatrolTaskServiceImpl.class).create(model);
                    SpringUtil.getBean(SupplierPatrolTaskServiceImpl.class).doSubmit(CollUtil.newArrayList(patrolTaskId));
                }
            }
        }
    }

}